home *** CD-ROM | disk | FTP | other *** search
/ Freelog 115 / FreelogNo115-MaiJuin2013.iso / Internet / Filezilla Server / FileZilla_Server-0_9_41.exe / source / interface / StatusCtrl.cpp < prev    next >
C/C++ Source or Header  |  2011-11-06  |  11KB  |  502 lines

  1. // StatusCtrl.cpp: Implementierungsdatei
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "StatusCtrl.h"
  6. #include "EnterSomething.h"
  7. #include "MainFrm.h"
  8.  
  9. #if defined(_DEBUG) && !defined(MMGR)
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14.  
  15. const COLORREF CStatusCtrl::m_ColTable[16] = {RGB(255, 255, 255),
  16.                                         RGB(0, 0, 0),
  17.                                         RGB(0, 0, 128),
  18.                                         RGB(0, 128, 0),
  19.                                         RGB(255, 0, 0),
  20.                                         RGB(128, 0, 0),
  21.                                         RGB(128, 0, 128),
  22.                                         RGB(128, 128, 0),
  23.                                         RGB(255, 255, 0),
  24.                                         RGB(0, 255, 0),
  25.                                         RGB(0, 128, 128),
  26.                                         RGB(0, 255, 255),
  27.                                         RGB(0, 0, 255),
  28.                                         RGB(255, 0, 255),
  29.                                         RGB(128, 128, 128),
  30.                                         RGB(192, 192, 192)
  31.                                         };
  32.  
  33. /////////////////////////////////////////////////////////////////////////////
  34. // CStatusCtrl
  35.  
  36. CStatusCtrl::CStatusCtrl()
  37. {
  38.     m_doPopupCursor = FALSE;
  39.     m_bEmpty = TRUE;
  40.     m_nMoveToBottom = 0;
  41.     m_nTimerID = 0;
  42.     m_headerPos = 0;
  43.     m_runTimer = 0;
  44. }
  45.  
  46. CStatusCtrl::~CStatusCtrl()
  47. {
  48. }
  49.  
  50.  
  51. BEGIN_MESSAGE_MAP(CStatusCtrl, CRichEditCtrl)
  52.     //{{AFX_MSG_MAP(CStatusCtrl)
  53.     ON_WM_ERASEBKGND()
  54.     ON_WM_CONTEXTMENU()
  55.     ON_WM_SETCURSOR()
  56.     ON_COMMAND(ID_OUTPUTCONTEXT_CLEARALL, OnOutputcontextClearall)
  57.     ON_COMMAND(ID_OUTPUTCONTEXT_COPYTOCLIPBOARD, OnOutputcontextCopytoclipboard)
  58.     ON_WM_CREATE()
  59.     ON_WM_TIMER()
  60.     ON_WM_RBUTTONUP()
  61.     ON_WM_MOUSEWHEEL()
  62.     //}}AFX_MSG_MAP
  63. END_MESSAGE_MAP()
  64.  
  65. /////////////////////////////////////////////////////////////////////////////
  66. // Behandlungsroutinen fⁿr Nachrichten CStatusCtrl 
  67.  
  68. BOOL CStatusCtrl::OnEraseBkgnd(CDC* pDC) 
  69. {
  70.     return TRUE;
  71. }
  72.  
  73. void CStatusCtrl::OnContextMenu(CWnd* pWnd, CPoint point) 
  74. {
  75.     ClientToScreen(&point);
  76.  
  77.     CMenu menu;
  78.     menu.LoadMenu(IDR_OUTPUTCONTEXT);
  79.  
  80.     CMenu* pPopup = menu.GetSubMenu(0);
  81.     ASSERT(pPopup != NULL);
  82.     CWnd* pWndPopupOwner = this;
  83.     //while (pWndPopupOwner->GetStyle() & WS_CHILD)
  84.     //    pWndPopupOwner = pWndPopupOwner->GetParent();
  85.  
  86.     if (!GetLineCount())
  87.     {
  88.         pPopup->EnableMenuItem(ID_OUTPUTCONTEXT_COPYTOCLIPBOARD,MF_GRAYED);
  89.         pPopup->EnableMenuItem(ID_OUTPUTCONTEXT_CLEARALL,MF_GRAYED);
  90.     }
  91.     HCURSOR    hCursor;
  92.     hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
  93.     m_doPopupCursor = TRUE;
  94.     SetCursor(hCursor);
  95.         
  96.     pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
  97.         pWndPopupOwner);
  98. }
  99.  
  100. BOOL CStatusCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  101. {
  102.     if (!m_doPopupCursor)
  103.     {
  104.         m_doPopupCursor = 0;
  105.         return CWnd::OnSetCursor(pWnd, nHitTest, message );
  106.     }
  107.     else
  108.         m_doPopupCursor = 0;
  109.     return 0;
  110. }
  111.  
  112. DWORD __stdcall CStatusCtrl::RichEditStreamInCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
  113. {
  114.     char* output = (char*)pbBuff;
  115.     
  116.     CStatusCtrl *pThis = (CStatusCtrl *)dwCookie;
  117.     if (pThis->m_headerPos != -1)
  118.     {
  119.         int len = pThis->m_RTFHeader.GetLength() - pThis->m_headerPos;
  120.         if (len > cb)
  121.         {
  122.             pThis->m_headerPos = cb;
  123.             len = cb;
  124.         }
  125.         else
  126.             pThis->m_headerPos = -1;
  127.  
  128.         memcpy(output, (const char*)pThis->m_RTFHeader, len);
  129.         *pcb = len;
  130.     }
  131.     else
  132.     {
  133.         *pcb = 0;
  134.         if (pThis->m_statusBuffer.empty())
  135.             return 0;
  136.         t_buffer &buffer = pThis->m_statusBuffer.front();
  137.         if (buffer.status != _T(""))
  138.         {
  139.             if (buffer.pos == -1)
  140.             {
  141.                 if (pThis->m_bEmpty)
  142.                 {
  143.                     pThis->m_bEmpty = false;
  144.                     memcpy(output, "\\cf", 3);
  145.                     output += 3;
  146.                     cb -= 3;
  147.                     *pcb += 3;
  148.                 }
  149.                 else
  150.                 {
  151.                     memcpy(output, "\\par \\cf", 8);
  152.                     output += 8;
  153.                     cb -= 8;
  154.                     *pcb += 8;
  155.                 }
  156.                 switch (buffer.type)
  157.                 {
  158.                 default:
  159.                 case 0:
  160.                     *(output++) = '2';
  161.                     break;
  162.                 case 1:
  163.                     *(output++) = '5';
  164.                     break;
  165.                 case 2:
  166.                     *(output++) = '3';
  167.                     break;
  168.                 case 3:
  169.                     *(output++) = '4';
  170.                     break;
  171.                 }
  172.                 buffer.pos = 0;
  173.             }
  174.             LPCTSTR status = buffer.status;
  175.             LPCTSTR p = status + buffer.pos;
  176.             while (*p && cb > 9)
  177.             {    
  178.                 switch (*p)
  179.                 {
  180.                 case '\\':
  181.                     *(output++) = '\\';
  182.                     *(output++) = '\\';
  183.                     cb -= 2;
  184.                     *pcb += 2;
  185.                     break;
  186.                 case '{':
  187.                     *(output++) = '\\';
  188.                     *(output++) = '{';
  189.                     cb -= 2;
  190.                     *pcb += 2;
  191.                     break;
  192.                 case '}':
  193.                     *(output++) = '\\';
  194.                     *(output++) = '}';
  195.                     cb -= 2;
  196.                     *pcb += 2;
  197.                     break;
  198.                 case '\r':
  199.                     break;
  200.                 case '\n':
  201.                     *(output++) = '\\';
  202.                     *(output++) = 's';
  203.                     *(output++) = 't';
  204.                     *(output++) = 'a';
  205.                     *(output++) = 't';
  206.                     *(output++) = 'u';
  207.                     *(output++) = 's';
  208.                     cb -= 7;
  209.                     *pcb += 7;
  210.                     break;
  211.                 default:
  212.                     if (*p > 127)
  213.                     {
  214.                         int w = sprintf(output, "\\u%d?", (unsigned short)*p);
  215.                         output += w;
  216.                         cb -= w;
  217.                         *pcb += w;
  218.                     }
  219.                     else
  220.                     {
  221.                         *(output++) = (char)*p;
  222.                         cb--;
  223.                         (*pcb)++;
  224.                     }
  225.                 }
  226.                 p++;
  227.  
  228.             }
  229.             if (!*p)
  230.             {
  231.                 pThis->m_statusBuffer.pop_front();
  232.                 if (pThis->m_statusBuffer.empty())
  233.                 {
  234.                     memcpy(output, "} ", 2);
  235.                     output += 2;
  236.                     *pcb += 2;
  237.                 }
  238.                 else
  239.                 {
  240.                     *(output++) = ' ';
  241.                     (*pcb)++;
  242.                 }
  243.             }
  244.             else
  245.                 buffer.pos = p - status;
  246.         }
  247.         else
  248.         {
  249.             pThis->m_statusBuffer.pop_front();
  250.             if (pThis->m_statusBuffer.empty())
  251.             {
  252.                 memcpy(output, "} ", 2);
  253.                 output += 2;
  254.                 *pcb += 2;
  255.             }
  256.         }
  257.     }
  258.  
  259.     return 0;
  260. }
  261.  
  262. void CStatusCtrl::OnOutputcontextClearall() 
  263. {
  264.     t_buffer buffer;
  265.     buffer.status = _T("");
  266.     buffer.pos = -1;
  267.     buffer.type = 0;
  268.     m_statusBuffer.push_back(buffer);
  269.  
  270.     DoStreamIn();
  271.  
  272.     SetSel(-1, -1);
  273.     LimitText(1000*1000);
  274.     
  275.     m_bEmpty = TRUE;
  276.     m_nMoveToBottom = 0;
  277. }
  278.  
  279. void CStatusCtrl::OnOutputcontextCopytoclipboard() 
  280. {
  281.     long nStart, nEnd;
  282.     GetSel(nStart, nEnd);
  283.     if (nStart == nEnd)
  284.     {
  285.         HideSelection(TRUE, FALSE);
  286.         SetSel(0, -1);
  287.         Copy();
  288.         SetSel(nStart, nEnd);
  289.         HideSelection(FALSE, FALSE);
  290.     }
  291.     else
  292.         Copy();
  293. }
  294.  
  295.  
  296. int CStatusCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  297. {
  298.     if (CRichEditCtrl::OnCreate(lpCreateStruct) == -1)
  299.         return -1;
  300.  
  301.     USES_CONVERSION;
  302.     
  303.     m_RTFHeader = "{\\rtf1\\ansi\\deff0";
  304.  
  305.     HFONT hSysFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
  306.  
  307.     LOGFONT lf;
  308.     CFont* pFont = CFont::FromHandle( hSysFont );
  309.     pFont->GetLogFont( &lf );
  310.  
  311.     LOGFONT m_lfFont;
  312.     pFont->GetLogFont(&m_lfFont);
  313.     
  314.     m_RTFHeader += "{\\fonttbl{\\f0\\fnil "+ CString(m_lfFont.lfFaceName)+";}}";
  315.     m_RTFHeader += "{\\colortbl ;";
  316.     for (int i=0; i<16; i++)
  317.     {
  318.         CString tmp;
  319.         tmp.Format(_T("\\red%d\\green%d\\blue%d;"), GetRValue(m_ColTable[i]), GetGValue(m_ColTable[i]), GetBValue(m_ColTable[i]));
  320.         m_RTFHeader+=tmp;
  321.     }
  322.     m_RTFHeader += "}";
  323.     
  324.     int pointsize = (-m_lfFont.lfHeight*72/ GetDeviceCaps(GetDC()->GetSafeHdc(), LOGPIXELSY))*2;
  325.     CString tmp;
  326.     tmp.Format(_T("%d"), pointsize);
  327.     m_RTFHeader += "\\uc1\\pard\\fi-200\\li200\\tx200\\f0\\fs"+tmp; //180*m_nAvgCharWidth;
  328.  
  329.     t_buffer buffer;
  330.     buffer.status = _T("");
  331.     buffer.pos = -1;
  332.     buffer.type = 0;
  333.     m_statusBuffer.push_back(buffer);
  334.  
  335.     m_headerPos = 0;
  336.  
  337.     DoStreamIn();
  338.  
  339.     SetSel(-1, -1);
  340.     LimitText(1000*1000);
  341.     
  342.     return 0;
  343. }
  344.  
  345. void CStatusCtrl::ShowStatus(LPCTSTR status, int nType)
  346. {
  347.     t_buffer buffer;
  348.     buffer.status = status;
  349.     buffer.type = nType;
  350.     buffer.pos = -1;
  351.  
  352.     m_statusBuffer.push_back(buffer);
  353.  
  354.     if (!m_runTimer)
  355.     {
  356.         Run();
  357.         m_runTimer = SetTimer(1339, 250, 0);
  358.     }
  359.  
  360.     return;
  361. }
  362.  
  363. void CStatusCtrl::Run()
  364. {
  365.     if (m_statusBuffer.empty())
  366.         return;
  367.  
  368.     m_headerPos = 0;
  369.  
  370.     CWnd *pFocusWnd = GetFocus();
  371.     if (pFocusWnd && pFocusWnd == this)
  372.         AfxGetMainWnd()->SetFocus();
  373.     
  374.     long nStart, nEnd;
  375.     GetSel(nStart, nEnd);
  376.     BOOL nScrollToEnd = FALSE;
  377.     
  378.     int num = 0;            //this is the number of visible lines
  379.     CRect rect;
  380.     GetRect(rect);
  381.     int height = rect.Height();
  382.     
  383.     for (int i = GetFirstVisibleLine();
  384.             i < GetLineCount() && GetCharPos(LineIndex(i)).y < height;
  385.             i++)
  386.         num++;
  387.  
  388.     if (GetFirstVisibleLine() + num+m_nMoveToBottom >= GetLineCount())
  389.         nScrollToEnd = TRUE;
  390.     HideSelection(TRUE, FALSE);
  391.     SetSel(-1, -1);
  392.  
  393.     DoStreamIn(SFF_SELECTION);
  394.  
  395.     int count = GetLineCount();
  396.     if (count > 1000)
  397.     {
  398.         count = count - 1000;
  399.         int index = LineIndex(count);
  400.         nStart -= index;
  401.         nEnd -= index;
  402.         if (nStart < 0)
  403.             nEnd = 0;
  404.         if (nEnd < 0)
  405.             nEnd = 0;
  406.         SetSel(0, index);
  407.         ReplaceSel(_T(""));
  408.     }
  409.  
  410.     SetSel(nStart, nEnd);
  411.     
  412.     if (pFocusWnd && pFocusWnd == this)
  413.         SetFocus();
  414.  
  415.     HideSelection(FALSE, FALSE);
  416.     if (nScrollToEnd)
  417.     {
  418.         if (nStart != nEnd && (LineFromChar(nStart) >= GetFirstVisibleLine() && LineFromChar(nStart) <= GetFirstVisibleLine() + num ||
  419.                                LineFromChar(nEnd) >= GetFirstVisibleLine() && LineFromChar(nEnd) <= GetFirstVisibleLine() + num))
  420.             LineScroll(1);
  421.         else 
  422.         {
  423.             m_nMoveToBottom++;
  424.             if (!m_nTimerID)
  425.                 m_nTimerID = SetTimer(654, 25, NULL);
  426.         }
  427.     }
  428. }
  429.  
  430. void CStatusCtrl::OnTimer(UINT_PTR nIDEvent) 
  431. {
  432.     if (nIDEvent == m_nTimerID)
  433.     {
  434.         if (m_nMoveToBottom)
  435.         {
  436.             SendMessage(WM_VSCROLL, SB_BOTTOM, 0);
  437.             m_nMoveToBottom = 0;
  438.         }
  439.         KillTimer(m_nTimerID);
  440.         m_nTimerID = 0;
  441.     }
  442.     else if (nIDEvent == static_cast<UINT>(m_runTimer))
  443.     {
  444.         KillTimer(m_runTimer);
  445.         m_runTimer = 0;
  446.         Run();
  447.     }
  448.     CRichEditCtrl::OnTimer(nIDEvent);
  449. }
  450.  
  451. void CStatusCtrl::OnRButtonUp(UINT nFlags, CPoint point) 
  452. {
  453.     ClientToScreen(&point);
  454.  
  455.     CMenu menu;
  456.     menu.LoadMenu(IDR_OUTPUTCONTEXT);
  457.     
  458.     CMenu* pPopup = menu.GetSubMenu(0);
  459.     ASSERT(pPopup != NULL);
  460.     CWnd* pWndPopupOwner = this;
  461.     //while (pWndPopupOwner->GetStyle() & WS_CHILD)
  462.     //    pWndPopupOwner = pWndPopupOwner->GetParent();
  463.     
  464.     if (!GetLineCount())
  465.     {
  466.         pPopup->EnableMenuItem(ID_OUTPUTCONTEXT_COPYTOCLIPBOARD,MF_GRAYED);
  467.         pPopup->EnableMenuItem(ID_OUTPUTCONTEXT_CLEARALL,MF_GRAYED);
  468.     }
  469.     HCURSOR    hCursor;
  470.     hCursor = AfxGetApp()->LoadStandardCursor( IDC_ARROW );
  471.     m_doPopupCursor = TRUE;
  472.     SetCursor(hCursor);
  473.     
  474.     pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
  475.         pWndPopupOwner);
  476. }
  477.  
  478. BOOL CStatusCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
  479. {
  480.     OSVERSIONINFO info = {0};
  481.     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  482.     GetVersionEx(&info);
  483.     if (info.dwMajorVersion >= 5)
  484.         return CRichEditCtrl::OnMouseWheel(nFlags, zDelta, pt);
  485.  
  486.     LineScroll(-zDelta / 120 * 3);
  487.  
  488.     return TRUE;
  489. }
  490.  
  491. void CStatusCtrl::DoStreamIn(int extraFlags)
  492. {
  493.     EDITSTREAM es;
  494.     es.dwCookie = (DWORD)this; // Pass a pointer to the CString to the callback function 
  495.     es.pfnCallback = RichEditStreamInCallback; // Specify the pointer to the callback function.
  496.     
  497. #ifdef _UNICODE
  498. //    extraFlags |= SF_UNICODE;
  499. #endif
  500.     StreamIn(extraFlags | SF_RTF, es); // Perform the streaming
  501. }
  502.